package com.study.config;

import com.study.jwt.JWTShiroRealm;
import com.study.jwt.filter.AnyRolesAuthorizationFilter;
import com.study.jwt.filter.JwtAuthFilter;
import com.study.shiro.AuthRealm;
import com.study.shiro.CustomCredentialsMatcher;
import com.study.shiro.MyShiroFilterFactoryBean;
import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.*;

/*********************************************************
 * @Author ONE_LLX
 * @Description shiro 配置管理器
 * @Date 15:35 2019/10/11
 * @Class ShiroConfig
 * @Version v1.0
 * 安全管理器
 * 配置Realm域
 * 密码比较器 -->
 * 代理如何生成？ 用工厂来生成Shiro的相关过滤器
 * 配置缓存：ehcache缓存
 *
 *********************************************************/
@Configuration
public class ShiroConfig {



    @Bean
    protected SessionStorageEvaluator sessionStorageEvaluator(){
        DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator();
        sessionStorageEvaluator.setSessionStorageEnabled(false);
        return sessionStorageEvaluator;
    }
    /**
     * 密码比较器
     */
    @Bean
    public SimpleCredentialsMatcher customCredentialsMatcher() {
        CustomCredentialsMatcher matcher=new CustomCredentialsMatcher();
        return matcher;
    }

    /**
     * 验证方式
     * @return
     */
    @Bean
    public AuthRealm myShiroRealm() {
        AuthRealm myShiroRealm = new AuthRealm();
        //将加密方式绑定到自定义的realm
        myShiroRealm.setCredentialsMatcher(customCredentialsMatcher());
        return myShiroRealm;
    }

    @Bean
    public Authenticator authenticator( ) {
        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
        JWTShiroRealm jwtShiroRealm=new JWTShiroRealm();
        List realms=new ArrayList();
        realms.add(myShiroRealm());//可以配置多个realm
        realms.add(jwtShiroRealm);
        authenticator.setRealms(realms);
        authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
        return authenticator;
    }

    /**
     * 安全管理器
     * @return
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setAuthenticator(authenticator());
        return securityManager;
    }


    //Filter工厂，设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new MyShiroFilterFactoryBean();
        // 必须设置 SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        MyAccessControlFilter filter=new MyAccessControlFilter();
        JwtAuthFilter jwtAuthFilter=new JwtAuthFilter();
        AnyRolesAuthorizationFilter rolesFilter=new AnyRolesAuthorizationFilter();
        Map<String, Filter> filterMap=new HashedMap();
        filterMap.put("jwtAuthFilter",jwtAuthFilter);
        filterMap.put("rolesFilter",rolesFilter);
        shiroFilterFactoryBean.setFilters(filterMap);
        // 拦截器
        Map<String,String> map = new HashMap<String, String>();
        map.put("/manager/login","anon");
        map.put("/**","authc");
        map.put("/*.*","authc");
        map.put("/**","jwtAuthFilter,rolesFilter");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    /**
     *
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor( ) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }


    @Bean(name = "postProcessor")
    public LifecycleBeanPostProcessor postProcessor(){
        LifecycleBeanPostProcessor postProcessor=new LifecycleBeanPostProcessor();
        return postProcessor;
    }

    @DependsOn(value = {"postProcessor"})
    @Bean
    public DefaultAdvisorAutoProxyCreator proxyCreator(){
        DefaultAdvisorAutoProxyCreator proxyCreator=new DefaultAdvisorAutoProxyCreator();
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

}
